package com.longkier.gx_library_springboot.Service;

import com.longkier.gx_library_springboot.entity.Admin;
import com.longkier.gx_library_springboot.entity.BookAdmin;
import com.longkier.gx_library_springboot.repository.AdminRepository;
import com.longkier.gx_library_springboot.repository.BookAdminRepository;

import lombok.RequiredArgsConstructor;
import org.apache.ibatis.annotations.Param;
import org.jetbrains.annotations.NotNull;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class AdminService {
    private final AdminRepository adminRepository;
    private final BookAdminRepository bookAdminRepository;
    private final PasswordEncoder passwordEncoder;

    //系统管理员service层
    /**
     * 检查指定的系统管理员用户名是否已被占用。
     *
     * @param username 要检查的系统管理员用户名
     * @return 如果系统管理员用户名已被占用，返回 true；否则返回 false
     */
    public boolean admin_UsernameTaken(String username) {
        return adminRepository.findByUsername(username).isPresent();
    }
    /**
     * 添加新系统管理员。
     * - 对系统管理员用户密码进行加密。
     * - 设置默认的状态、创建时间和更新时间。
     * - 将系统管理员用户信息保存到数据库。
     *
     * @param admin 要注册的系统管理员用户对象
     */
    public Admin createAdmin(@NotNull Admin admin) {
        admin.setPassword(passwordEncoder.encode(admin.getPassword())); // 加密密码
        admin.setStatus(1);
        admin.setCreateTime(LocalDateTime.now());
        admin.setUpdateTime(LocalDateTime.now());
        adminRepository.save(admin);
        return admin;
    }
    /**
     * 批量删除系统管理员。
     *
     * @param AdminIds 要删除的系统管理员用户 ID 列表
     * @return 如果删除成功，返回 true；否则返回 false
     */
    @Transactional
    public boolean batchDeleteAdmins(@Param("AdminIds") List<Long> AdminIds) {
        if (AdminIds == null || AdminIds.isEmpty()) {
            return false;  // 没有要删除的用户ID
        }
        // 确保删除操作成功
        int deletedCount = adminRepository.deleteAdminAllByIdInBatch(AdminIds);
        return deletedCount == AdminIds.size();  // 如果删除的数量与请求的数量一致，才算成功
    }


    /**
     * 分页获取系统管理员列表。
     *
     * @param page 当前页码（从 0 开始）
     * @param size 每页大小
     * @param status 状态（可选）
     * @param username 用户名（可选）
     * @param adminName 管理员名称（可选）
     * @return 系统管理员分页对象
     */
    public Page<Admin> getAllAdmins(int page, int size,Integer status, String username, String adminName) {
        Pageable pageable = PageRequest.of(page, size);
        Page<Admin> adminPage = adminRepository.findAdminByCriteria(status, username, adminName, pageable);
        adminPage.getContent().forEach(admin -> admin.setPassword(null));//隐藏密码
        return adminPage;
    }

    /**
     * 更新系统管理员信息。
     * - 使用提供的系统管理员用户对象中的用户名、管理员名、密码和当前时间更新现有用户信息。
     *
     * @param id 更新系统管理员用户ID
     * @param AdminDetails 包含更新信息的系统管理员用户对象
     * @return 如果更新成功，返回 true；否则返回 false
     */
    public Optional<Admin> updateAdminService(Long id, Admin AdminDetails) {
        return adminRepository.findById(id)
                .map(existingAdmin -> {
                    existingAdmin.setUsername(AdminDetails.getUsername());
                    existingAdmin.setAdminName(AdminDetails.getAdminName());
                    existingAdmin.setUpdateTime(LocalDateTime.now());
                    if (existingAdmin.getPassword()!=null){
                        existingAdmin.setPassword(passwordEncoder.encode(AdminDetails.getPassword())); // 更新并加密新密码
                    }
                    return adminRepository.save(existingAdmin);
                });
    }

    /**
     * 批量设置系统管理员启用状态。
     *
     * @param AdminIds 要更新的用户 ID 列表
     * @param status  新的状态
     * @return 如果更新成功，返回 true；否则返回 false
     */
    public boolean batchUpdateAdminStatus(@Param("userIds,status")List<Long> AdminIds, Integer status) {
        List<Admin> Admins = adminRepository.findAllById(AdminIds);
        if (Admins.isEmpty()) {
            return false;
        }
        Admins.forEach(user -> {
            user.setStatus(status);
            user.setUpdateTime(LocalDateTime.now());
        });
        adminRepository.saveAll(Admins);
        return true;
    }


    // 图书管理员service层
    /**
     * 检查指定的图书管理员用户名是否已被占用。
     *
     * @param username 要检查的图书管理员用户名
     * @return 如果图书管理员用户名已被占用，返回 true；否则返回 false
     */
    public boolean bookAdminUsernameTaken(String username) {
        return bookAdminRepository.findByUsername(username).isPresent();
    }

    // 图书管理员service层
    /**
     * 检查指定的图书管理员邮箱是否已被占用。
     *
     * @param email 要检查的图书管理员邮箱
     * @return 如果图书管理员邮箱已被占用，返回 true；否则返回 false
     */
    public boolean bookAdminEmailTaken(String email) {
        return bookAdminRepository.findByEmail(email).isPresent();
    }

    /**
     * 添加新系统管理员。
     * - 对图书管理员密码进行加密。
     * - 设置默认的状态、创建时间和更新时间。
     * - 将图书管理员信息保存到数据库。
     *
     * @param bookAdmin 要注册的图书管理员对象
     */
    public BookAdmin createBookAdmin(BookAdmin bookAdmin) {
        bookAdmin.setPassword(passwordEncoder.encode(bookAdmin.getPassword())); // 加密密码
        bookAdmin.setStatus(1);
        bookAdmin.setEmail(bookAdmin.getEmail());
        bookAdmin.setUpdateTime(LocalDateTime.now());
        bookAdmin.setCreateTime(LocalDateTime.now());
        bookAdminRepository.save(bookAdmin);
        return bookAdmin;
    }

    /**
     * 批量删除图书管理员。
     *
     * @param bookAdminIds 要删除的图书管理员 ID 列表
     * @return 如果删除成功，返回 true；否则返回 false
     */
    @Transactional
    public boolean batchDeleteBookAdmin(@Param("bookAdminIds") List<Long> bookAdminIds) {
        if (bookAdminIds == null || bookAdminIds.isEmpty()) {
            return false;
        }
        int deletedCount = bookAdminRepository.deleteBookAdminAllByIdInBatch(bookAdminIds);
        return deletedCount == bookAdminIds.size();
    }

    /**
     * 分页获取图书管理员列表。
     *
     * @param page 当前页码（从 0 开始）
     * @param size 每页大小
     * @param status 用户状态（可选）
     * @param username 用户名（可选）
     * @param email 邮箱（可选）
     * @param bookAdminName 图书管理员名称（可选）
     * @return 图书管理员分页对象
     */
    public Page<BookAdmin> getAllBookAdmins(int page, int size,Integer status, String username,String email, String bookAdminName) {
        Pageable pageable = PageRequest.of(page,size);
        Page<BookAdmin> bookAdminPage = bookAdminRepository.findBookAdminByByCriteria(status, username, bookAdminName,email,pageable);
        bookAdminPage.getContent().forEach(bookAdmin -> bookAdmin.setPassword(null));
        return bookAdminPage;
    }

    /**
     * 更新系统管理员信息。
     * - 使用提供的用户对象中的用户名、密码、图书管理员名、邮箱和当前时间更新现有用户信息。
     *
     * @param id 更新图书管理员ID
     * @param bookAdminDetails 包含更新信息的图书管理员对象
     * @return 如果更新成功，返回 true；否则返回 false
     */
    public Optional<BookAdmin> updateBookAdmin(Long id, BookAdmin bookAdminDetails) {
        return bookAdminRepository.findById(id)
                .map(existingBookAdmin -> {
                    existingBookAdmin.setUsername(bookAdminDetails.getUsername());
                    existingBookAdmin.setBookAdminName(bookAdminDetails.getBookAdminName());
                    existingBookAdmin.setEmail(bookAdminDetails.getEmail());
                    existingBookAdmin.setUpdateTime(LocalDateTime.now());
                    if(bookAdminDetails.getPassword()!=null){
                        existingBookAdmin.setPassword(passwordEncoder.encode(bookAdminDetails.getPassword())); // 更新并加密新密码
                    }
                    return bookAdminRepository.save(existingBookAdmin);
                });
    }

    /**
     * 批量设置图书管理员启用状态。
     *
     * @param bookAdminIds 要更新的用户 ID 列表
     * @param status  新的状态
     * @return 如果更新成功，返回 true；否则返回 false
     */
    public boolean batchUpdateBookAdminStatus(@Param("userIds,status")List<Long> bookAdminIds, Integer status) {
        List<BookAdmin> bookAdmins = bookAdminRepository.findAllById(bookAdminIds);
        if (bookAdmins.isEmpty()) {
            return false;
        }
        bookAdmins.forEach(user -> {
            user.setStatus(status);
            user.setUpdateTime(LocalDateTime.now());
        });
        bookAdminRepository.saveAll(bookAdmins);
        return true;
    }
}
